package com.haoran.springboot.demo;



import java.lang.reflect.Method;
import java.util.*;

/**
 * 排序工具类
 * 以归并排序算法实现，请确保字段中为数字内容 不要出现字符
 * 目前存在的问题为 高精度数据类型可能会丢精度
 * 排序结束后 会标记 排名
 * 比如：90|1
 *       89|2
 *       ...
 */
public class sortUtil {
    /**
     * 归并排序
     *
     * @param array 需要排序的数组
     * @return
     */
    public static Double[] MergeSort(Double[] array) {
        if (array.length < 2) return array;
        int mid = array.length / 2;
        Double[] left = Arrays.copyOfRange(array, 0, mid);
        Double[] right = Arrays.copyOfRange(array, mid, array.length);
        return merge(MergeSort(left), MergeSort(right));
    }
    /**
     * 归并排序——将两段排序好的数组结合成一个排序数组
     *
     * @param left (左列)
     * @param right （右列）
     * @return
     */
    public static Double[] merge(Double[] left, Double[] right) {
        Double[] result = new Double[left.length + right.length];

        for (int index = 0, i = 0, j = 0; index < result.length; index++) {
            if (i >= left.length)
                result[index] = right[j++];
            else if (j >= right.length)
                result[index] = left[i++];
            else if (left[i] > right[j])
                result[index] = right[j++];
            else
                result[index] = left[i++];
        }
        return result;
    }
    /**
     * 给指定一些字段做排序 (小数字段排序)
     * @param list
     * @param fields
     */
    public static void fieldSorting(List<Object> list, List<String> fields){
        if(fields==null ||list==null){
            return;
        }
        for (String i:fields){
            setTop(list,i);
        }
    }
    /**
     * 利用反射机制 动态做数据排序
     * @param list 数据源
     * @param failname 字段名
     */
    public static void setTop(List<Object> list,String failname) {
        if (failname==null){
            return;
        }
        String str1=failname.substring(0, 1).toUpperCase();//A:截取0~1之间的字符，并转为大写
        String str2=failname.substring(1).toLowerCase();//把1之后包括1之后的字母转为小写
        failname=str1+str2;
        System.out.println(failname);
        try{
            //反射
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            Class clazz = loader.loadClass("com.haoran.springboot.model.Dept");
            Method setFail=clazz.getMethod("set"+failname,String.class);
            Method getFail=clazz.getMethod("get"+failname);
            List<Double> muns=new ArrayList<>();
            Map<Double,Object> map=new HashMap<Double,Object>();
            for (Object i:list){
                Object fali=getFail.invoke(i);
                map.put(Double.parseDouble(fali.toString()),i);
                muns.add(Double.parseDouble(fali.toString()));
            }
            Double[] strings = new Double[muns.size()];
            muns.toArray(strings);
            strings=MergeSort(strings);
            for (Double i:strings) {
                Object name=map.get(i);
                int index=strings.length- Arrays.binarySearch(strings,i);
                setFail.invoke(name,i+"|"+index);
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }

    }

}
